<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 视图(view)  页面,用于做html展示 -->
    <div id="app">
        <p></p>
        <p></p>
    </div>
</body>
<script>
    // Object.defineProperty()    
    // 1. 配置对象的某个属性(默认值, 是否可以修改, 是否可以枚举, 是否可以重新配置/删除)
    // 2. 数据劫持  => 对 对象的某个属性取值和赋值时 可以被Object.defineProperty检测到,执行对应的回调函数


    // 用法1: 
    /* let data = {};
    Object.defineProperty(data,"msg",{
        value:"hello world",
        writable:false,
        enumerable:false,
        configurable:false, 
    })
    Object.defineProperty(data,"msg",{
        value:"hello world",
        writable:true,
        enumerable:true,
        configurable:true, 
    })
    console.log(data);
    
    data.msg = "hello vue!!"

    delete data.msg;
    console.log(data); */

    let data = {
        msg:"hello world",
        count: 100,
    }

    let _defaultMsg = data["msg"];  // 中间变量 提前存储msg的值
    Object.defineProperty(data,"msg",{
        enumerable:true,
        configurable:true, 
        get:function(){ // 对某个属性取值时执行对应的回调函数 => 回调函数的返回值就是获取的值
            console.log("取值拦截");

            // return "abc"; // 返回abc
            // return false;
            // return undefined; //默认返回 (不允许用户对该属性取值 => 私有属性)

            // return data.msg;  // 死递归!!
            return _defaultMsg;
        },
        set:function(newVal){// 对某个属性赋值时执行对应的回调函数(回调函数有一个形参,接收新值)
            console.log("赋值拦截",newVal);

            _defaultMsg = newVal;  // data.msg 取值依赖于中间变量 _defaultMsg

            // return undefined; //默认返回undefined (不允许用户对该属性赋值  => 只读属性)
        }
    })

    console.log(data);
    // console.log(data.msg); // 取值

    data.msg = "hello vue!!!";

    console.log(data.msg);

    
    


</script>


</html>